﻿using CorpStore.Common;
using CorpStore.Models;
using Newtonsoft.Json;
using StoreHelper;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.Foundation;
using Windows.Storage;
using Windows.Storage.Search;
using Windows.UI.Core;
using Windows.UI.Xaml.Controls;

namespace CorpStore.ViewModels
{
    /// <summary>
    /// This is the view model for MainPage.
    /// </summary>
    class MainViewModel : BaseViewModel
    {
        private StorageFileQueryResult _query;

        public MainViewModel()
        {
        }

        // true when the progress ring should be showing
        private bool progressIsActive;
        public bool ProgressIsActive
        {
            get { return progressIsActive; }
            set { progressIsActive = value; OnPropertyChanged("ProgressIsActive"); }
        }

        private PackageInfoGroupList groupList;
        public PackageInfoGroupList GroupList
        {
            get { return groupList; }
            set { groupList = value; OnPropertyChanged(""); OnPropertyChanged("CorpStoreTitle"); OnPropertyChanged("GroupsExist"); }
        }

        public bool GroupsExist
        {
            get { return (groupList != null && groupList.Groups.Count > 0); }
        }

        public string CorpStoreTitle
        {
            get 
            {
                return App.StoreTitle;
            }
        }

        private int selectedFlipIndex;
        public int SelectedFlipIndex
        {
            get { return selectedFlipIndex; }
            set { SetProperty<int>(ref selectedFlipIndex, value); }
        }


        public async Task<bool> InitAsync(NavData navData)
        {
            groupList = await PackageIO.LoadApplicationGroupsAsync();

            if (groupList != null)
            {
                App.StoreTitle = getSetting(groupList, "corpStoreTitle", "Corp Store");
                App.PrivacyContact = getSetting(groupList, "privacyContact", "Unknown");

                GroupList = groupList;
            }

            return (groupList != null);
        }


        private string getSetting(PackageInfoGroupList groupList, string settingName, string defaultValue)
        {
            string strValue = defaultValue;

            if (groupList != null)
            {
                if (groupList.Settings.Keys.Contains(settingName))
                    strValue = groupList.Settings[settingName] ?? defaultValue;
            }

            return strValue;
        }


        public List<PackageInfo> GetAppsByName(string nameSubstring)
        {
            return GroupList.Groups.SelectMany(g => g.Applications).Where(a => a.DisplayName.IndexOf(nameSubstring, StringComparison.OrdinalIgnoreCase) != -1).ToList<PackageInfo>();
        }


        public async Task<bool> checkEnvironmentAsync(TypedEventHandler<IStorageQueryResultBase, Object> OnFilesChanged, bool forceRefresh = true)
        {
            bool blnOK = false;

            // turn off our progress ring
            ProgressIsActive = false;

            if (!await StoreHelper.GenIO.FileExistsAsync(ApplicationData.Current.LocalFolder, "MasterCatalog.json"))
            {
                await logInfoWithMsg("Master Catalog not found.  Click [Ok] to send a request to create it...");
                blnOK = await LaunchUpdateMasterRequestAsync(OnFilesChanged);
            }
            else
            {
                // master catalog exists - just reload our groups
                if (forceRefresh)
                    blnOK = await InitAsync(null);
                else
                    blnOK = true;
            }

            return blnOK;
        }

        public async Task<bool> LaunchUpdateMasterRequestAsync(TypedEventHandler<IStorageQueryResultBase, Object> OnFilesChanged)
        {
            bool blnOK = false;

            try
            {
                // our masterCatalog.json file does not exist - attempt to create it
                Uri uri = new Uri(string.Format("corpstore://updateMasterCatalog?mode=launchApp"));
                logInfo("Attempting to create masterCatalog.json through CorpStoreServer; launch uri is '{0}'...", uri.ToString());

                // turn on our progress ring
                ProgressIsActive = true;

                if (await Windows.System.Launcher.LaunchUriAsync(uri, new Windows.System.LauncherOptions() { DesiredRemainingView = Windows.UI.ViewManagement.ViewSizePreference.UseMore }))
                {
                    _query = ApplicationData.Current.LocalFolder.CreateFileQuery();
                    _query.ContentsChanged += OnFilesChanged;
                    var files = await _query.GetFilesAsync();
                    blnOK = true;
                }
                else
                {
                    // turn off our progress ring
                    ProgressIsActive = false;

                    logErrWithMsg("Error launching corpStoreServer to create masterCatalog.json; make sure that CorpStoreServer has been registered with the 'corpStore' protocol");
                }
            }
            catch (Exception ex)
            {
                logErrWithMsg("Error launching corpStoreServer to create master catalog - unhandled exception: {0}", ex.Message);
                ProgressIsActive = false;
            }

            return blnOK;
        }


        public void StopListeningToFilesChanged(TypedEventHandler<IStorageQueryResultBase, Object> OnFilesChanged)
        {

            _query.ContentsChanged -= OnFilesChanged;
        }


        private void logErr(string msg, params object[] p)
        {
            App.LogErr(msg, p);
        }

        private void logErrWithMsg(string msg, params object[] p)
        {
            App.LogErrWithMsg(msg, p);
        }

        private void logInfo(string msg, params object[] p)
        {
            App.LogInfo(msg, p);
        }

        private Task logInfoWithMsg(string msg, params object[] p)
        {
            return App.LogInfoWithMsg(msg, p);
        }

    }
}
